// buileTAC CASE NUMBER 219行 free(temnum)会卡死 NEWTEMPNUM中也有这种情况
// .y ast.c文件有BUG 导致.y文件实参有点奇怪
#include "TAC.h"
#include "Hash_SIGNAL.h"



char * FuncName;// 标识当前所处在哪个函数内
List* IDorCONST;
//List* returnval;
int NODE_ID = 0;
int NodeFuncID = 1;
//extern int pointerflag = 0;
//int func_count = 0;
//HashMap* FuncMap;
//FuncMap = HashMapInit();

void initlistmap()
{
    // 符号栈
    IDorCONST = ListInit();
    //returnval = ListInit();
    //FuncMap = HashMapInit();
    // 初始化符号表
    initFuncMap();
    // '当前函数' 指向NULL 表示全局变量
    FuncName = NULL;
}

pTAC newTACnode()
{
    pTAC node = malloc(sizeof(TAC));
    if (node == NULL)
    {
        printf("run out of memory.\n");
        exit(0);
    }
    memset(node, 0, sizeof(TAC));
    node->last = node;
    node->next = NULL;
    return node;
}

// pTAC1 as head
void conect_TAC(pTAC* pTAC1, pTAC* pTAC2) //可能pTAC1、2是空
{
    if (*pTAC1 == NULL || *pTAC1 == 0)
    {
        *pTAC1 = *pTAC2;
        return;
    }
    if (*pTAC2 == NULL || *pTAC2 == 0)
    {
        
        return;
    }
    (*pTAC1)->last->next = *pTAC2;
    pTAC tem = (*pTAC1)->last;
    (*pTAC1)->last = (*pTAC2)->last;
    (*pTAC2)->last = tem;
}

char* newTempID(int FuncFrom)
{
    /*
    char *a = malloc(sizeof(int)*6) ;
    a[0] = 't';
    int tem = NodeFuncID;
    
    a[1] = tem/1000 + 48;
    //printf("%d",tem/1000 + 48);
    
    tem = tem - (tem/1000)*1000;
    a[2] = tem/100 +48;
    tem = tem - (tem/100)*100;
    a[3] = tem/10 +48;
    tem = tem - (tem/10)*10;
    a[4] = tem + 48;
    a[5] = 0;
    NodeFuncID++;
    */
    int i = NodeFuncID;
    NodeFuncID++;
    int j =i;
    int size = 1;
    for (i = i/10; i!=0; size++)
    {
        i = i/10;
    }
    char* temnum = malloc(sizeof(char)*(size));
    char* num = malloc(sizeof(char)*(size + 3));
    num[0] = '%';num[1] = 't';num[size+2] = 0;
    //num[0] = 't';num[size+1] = 0;
    //itoa(j,temnum ,10);
    sprintf(temnum, "%d",j);
    for (size_t i = 0; i < size+1; i++)
    {
        num[i+2] = temnum[i];
    }
    //free(temnum);
    // 临时变量用不用放符号表里面，我觉得不用
    //putinsignal(FuncFrom, 0, tok_INT, 0, NULL, num);
    
    //！;//放入符号表
    return num;
    //生成问题;;
}

void backfill(pTAC node, int start, int end)
{
    pTAC fill = node;
    for (;fill->next != NULL; fill = fill->next)
    {
        if (fill->type == tok_BREAK)
        {
            fill->type = TACType_Go;
            fill->dest = buildNUM(end);
        }
        if (fill->type == tok_CONTINUE)
        {
            fill->type = TACType_Go;
            fill->dest = buildNUM(start);
        }
    }
    
}

// 将NUM转换成字符串
char* buildNUM(int i)
{
    int j =i;
    int size = 1;
    for (i = i/10; i!=0; size++)
    {
        i = i/10;
    }
    char* temnum = malloc(sizeof(char)*(size));
    char* num = malloc(sizeof(char)*(size + 2));
    num[0] = '#';num[size+1] = 0;
    //itoa(j,temnum ,10);
    sprintf(temnum,"%d",j);
    for (size_t i = 0; i < size; i++)
    {
        num[i+1] = temnum[i];
    }
    return num;
}

int handleconstexps(past node, int** dim)
{
    int dimcount = 0;
    for (past cur = node; cur != NULL; cur = cur->Ast_union.node.next)
    {
        dimcount++;
    }
    
    int *temdim = malloc(sizeof(int) * dimcount);
    int i = 0;
    for (past cur = node; cur != NULL; cur = cur->Ast_union.node.next)
    {
        temdim[i] = cur->Ast_union.node.left->Ast_union.node.middle->Ast_union.ivalue;
        i++;
    }
    *dim = temdim;
    return dimcount;
}

// 将压入栈中的字符串取出
char* ListGet()
{
    void * get;
    ListGetFront(IDorCONST, &get);
    char * str = get;
    //ListPopFront(IDorCONST);
    return str;
}

pTAC buildTAC(past node, int FuncFrom)
{
    // 当节点为空返回空指针
    if (NULL == node)
    {
        return NULL;
    }

    // 从.y中来，记录首节点
    int flag = 0;
    if (-1 == FuncFrom)
    {
        FuncFrom++;
        flag = -1;
    }

    pTAC RETURNTAC = NULL;
    switch (node->ast_ID)
    {
    case tok_ID://ID名进行压栈操作
        ListPushFront(IDorCONST, node->Ast_union.IDentifier);
        break;
    case Number:// 将常量转成 %t1 = #123 型
        node = node->Ast_union.node.middle;
        RETURNTAC = newTACnode();
        RETURNTAC->node_ID = NODE_ID;
        NODE_ID++;
        RETURNTAC->type = TACType_Def;
        char * tempID =  newTempID(FuncFrom);
        RETURNTAC->dest = tempID;
        int i = node->Ast_union.ivalue;
        int size = 1;
        for (i = i/10; i!=0; size++)
        {
            i = i/10;
        }
        char* temnum = malloc(sizeof(char)*(size));
        char* num = malloc(sizeof(char)*(size + 2));
        num[0] = '#';num[size+1] = 0;
        //itoa(node->Ast_union.ivalue,temnum ,10);
        sprintf(temnum,"%d",node->Ast_union.ivalue);
        for (size_t i = 0; i < size; i++)
        {
            num[i+1] = temnum[i];
        }
        //free(temnum);// BUG会卡死在这
        RETURNTAC->right = num;//char * 参数为 #0之类的，注意指针转化
        ListPushFront(IDorCONST, tempID);
        //free(tempID);
        //压栈操作
        break;
    case FuncDef:
        RETURNTAC = build_FuncDef_TAC(node, FuncFrom);
        break;
    case FuncFParam:
        RETURNTAC = build_FuncFParam_TAC(node, FuncFrom);
        break;
    case VarDecl:
        RETURNTAC = build_VarDecl_TAC(node, FuncFrom);
        break;
    case VarDef:
        RETURNTAC = build_VarDef_TAC(node, FuncFrom);
        break;
    case InitVal:
        RETURNTAC = build_InitVal_TAC(node, FuncFrom);
        break;
    case ConstDecl:
        RETURNTAC = build_ConstDecl_TAC(node, FuncFrom);
        break;
    case ConstDef:
        RETURNTAC = build_ConstDef_TAC(node, FuncFrom);
        break;
    case ConstExps:
        RETURNTAC = build_ConstExps_TAC(node, FuncFrom);
        break;
    case ConstInitVal:
        RETURNTAC = build_ConstInitVal_TAC(node, FuncFrom);
        break;
    case Block:
        RETURNTAC = build_Block_TAC(node, FuncFrom);
        break;
    case Stmt:
        RETURNTAC = build_Stmt_TAC(node, FuncFrom);
        break;
    case LVal:
        RETURNTAC = build_LVal_TAC(node, FuncFrom);
        break;
    case Exps:
        RETURNTAC = build_Exps_TAC(node, FuncFrom);
        break;
    case UnaryExp:
        RETURNTAC = build_UnaryExp_TAC(node, FuncFrom);
        break;
    case FuncRParams:
        RETURNTAC = build_FuncRParams_TAC(node, FuncFrom);
        break;
    case Expr:
        RETURNTAC = build_Expr_TAC(node, FuncFrom);
        break;
    default:
        break;
    }
    // 判断是否是首节点，若是进行下一步操作，以后处理的接口
    if (-1 == flag)
    {
        printfTAC(RETURNTAC);
        return NULL;
    }
    return RETURNTAC;
}

pTAC build_FuncDef_TAC(past node, int FuncFrom)//有next!
{
    // 生成函数开头TAC TACType_DefFunc
    pTAC FuncDef = newTACnode();
    FuncDef->node_ID = NODE_ID;
    NODE_ID++;
    FuncDef->type = (enum TACType)TACType_DefFunc;
    FuncDef->dest = node->Ast_union.node.left->Ast_union.IDentifier;
    
    // 将 所在函数 (名称) 改为当前函数
    FuncName = FuncDef->dest;

    // 置入 函数 符号表 HashMap* Funcsignal;(见HASH_signal.c)
    // 参数 函数名，函数返回值，函数开始位置
    insertFuncSignal(FuncDef->dest, node->Ast_union.node.t_Token1, FuncDef->node_ID);
    
    // 生成读取形参的TAC
    pTAC FuncFParams = buildTAC(node->Ast_union.node.middle, FuncDef->node_ID);
    
    // 生成代码块TAC
    pTAC Block = buildTAC(node->Ast_union.node.right, FuncDef->node_ID);
    
    // 生成函数结尾TAC TACType_EndFunc
    pTAC Funcend = newTACnode();
    Funcend->node_ID = NODE_ID;
    Funcend->type = TACType_EndFunc;
    Funcend->dest = node->Ast_union.node.left->Ast_union.IDentifier;
    NODE_ID++;
    
    //op = 声明了多少变量;
    FuncDef->op = getParamsNum(FuncName);
    // 将 所在函数 (名称) 改为当前函数
    FuncName = NULL;

    // 生成NEXT节点
    pTAC TAC_next = buildTAC(node->Ast_union.node.next, NODE_ID);
     
    conect_TAC(&FuncDef, &FuncFParams);
    conect_TAC(&FuncDef, &Block);
    conect_TAC(&FuncDef, &Funcend);
    conect_TAC(&FuncDef, &TAC_next);
    
    return FuncDef;
}

pTAC build_FuncFParam_TAC(past node, int FuncFrom)//有next！
{
    //newVarIDecl()！;//node->Ast_union.node.left == ID//只传入声明信息不初始化//1220扔到.y去生成//？
    pTAC FuncFParam = newTACnode();
    FuncFParam->type = TACType_Param;
    
    FuncFParam->dest = node->Ast_union.node.left->Ast_union.IDentifier;
    
    if (-1 == node->Ast_union.node.t_Token2)// 非数组
    {
        // 放入符号表 ... 以后只有类型检查能用上了
        pVarsValue varsvalue = initpVarsValue(0, node->Ast_union.node.t_Token1, 0, NULL);
        InsertVars(FuncName, FuncFParam->dest, varsvalue);
    }
    else 
    {
        FuncFParam->op = '*';
        
        // node->Ast_union.node 是当前形参节点， right 是EXPS 节点 EXPS next 是 EXPS 节点
        // 即 (exp) . next -> (exp) . next -> (exp) .... (exp)
        
        if (1 == node->Ast_union.node.t_Token2)// 不定长数组
        {
            int dimcount = 1;
            for (past cur = node->Ast_union.node.right; cur != NULL; cur = cur->Ast_union.node.next)
            {
                dimcount++;
            }
            int *dim = malloc(sizeof(int) * dimcount);
            dim[0] = -1;

            // 将维度信息依次读入dim中
            // 假设Exp全是数字，
            // 没有表达式（Expr），
            // 没有调用变量，即使调用也是全局变量，存值的必要性
            // （亟待完善）表达式 & 存值
            // 在假设是值的情况下 Exp . left -> Number . middle -> IntConst . ivalue
            // 读出维度信息
            int i = 1;
            for (past cur = node->Ast_union.node.right; NULL != cur; cur = cur->Ast_union.node.next)
            {
                dim[i] = cur->Ast_union.node.left->Ast_union.node.middle->Ast_union.ivalue;
                i++;
            }
            //放入符号表
            pVarsValue varsvalue = initpVarsValue(0, node->Ast_union.node.t_Token1, dimcount, dim);
            InsertVars(FuncName, FuncFParam->dest, varsvalue);
        }
        else//( 0 == node->Ast_union.node.t_Token2)// 定长数组
        {
            int dimcount = 0;
            for (past cur = node->Ast_union.node.right; cur != NULL; cur = cur->Ast_union.node.next)
            {
                dimcount++;
            }
            int *dim = malloc(sizeof(int) * dimcount);

            // 同上
            int i = 0;
            for (past cur = node->Ast_union.node.right; NULL != cur; cur = cur->Ast_union.node.next)
            {
                dim[i] = cur->Ast_union.node.left->Ast_union.node.middle->Ast_union.ivalue;
                i++;
            }
            //放入符号表
            pVarsValue varsvalue = initpVarsValue(0, node->Ast_union.node.t_Token1, dimcount, dim);
            InsertVars(FuncName, FuncFParam->dest, varsvalue);
        }
    }
    // 如果数组参数需要计算 故放后面
    FuncFParam->node_ID = NODE_ID;
    NODE_ID++;
    pTAC FuncFParamss = buildTAC(node->Ast_union.node.next, NODE_ID);
    conect_TAC(&FuncFParam, &FuncFParamss);
    return FuncFParam;
    /*
    //非数组情况//数组情况在传参的时候添加维度信息
        if (1 == node->Ast_union.node.t_Token2)//传入数组的情况
        {
            //处理数组
            //int* temdim;
            int dimcount = 1;
            for (past cur = node->Ast_union.node.right; cur != NULL; cur = cur->Ast_union.node.next)
            {
                dimcount++;
            }
            int *temdim = malloc(sizeof(int) * dimcount);
            temdim[0] = -1;
            int i = 1;
            for (past cur = node->Ast_union.node.right; cur != NULL; cur = cur->Ast_union.node.next)
            {
                temdim[i] = cur->Ast_union.node.left->Ast_union.node.middle->Ast_union.ivalue;
                i++;
            }
            //*dim = temdim;
            //return dimcount;

            //int dimcount = handleconstexps(node->Ast_union.node.middle, &temdim);
            //放入符号表
            
            int sum = 1;
            for (size_t i = 0; i < dimcount; i++)
            {
                sum = sum * temdim[i];
            }
            //putinsignal(FuncFrom, 0, tok_INT, dimcount, temdim, node->Ast_union.node.left->Ast_union.IDentifier);
            
            
        }
        else// 非数组传入情况
        {
            
        }

        TAC_FuncFParam->node_ID = NODE_ID;
        NODE_ID++;
        pTAC TAC_FuncFParamss = buildTAC(node->Ast_union.node.next, NODE_ID);
        
    conect_TAC(&TAC_FuncFParam, &TAC_FuncFParamss);
    return TAC_FuncFParam;
    */
}

pTAC build_VarDecl_TAC(past node, int FuncFrom)//有next!//中继节点
{
    pTAC VarDef = buildTAC(node->Ast_union.node.left, FuncFrom);
    pTAC next = buildTAC(node->Ast_union.node.next, FuncFrom);
    conect_TAC(&VarDef, &next);
    return VarDef;
}

pTAC build_VarDef_TAC(past node, int FuncFrom)//有next！
{
    //node->Ast_union.node.middle = ConstExps
    if (NULL == node->Ast_union.node.middle)//非数组
    {
        // putinsignal(FuncFrom, 0, tok_INT, 0, NULL, node->Ast_union.node.left->Ast_union.IDentifier);
        //？;//声明分数组非数组？//1220扔到.y去生成//处理InitVal//InitVal->exp->unaryexp->primaryexp->...;//pTAC middle = buildTAC(node->Ast_union.node.middle, FuncFrom);//newVarIDecl()！;//处理INITVAL放到这个生成函数里面？初始化的TAC呢？//1220扔到.y去生成shan
        pTAC VarDef = newTACnode();
        // 要先处理的等号右边的值
        pTAC left = buildTAC(node->Ast_union.node.right, FuncFrom);
        VarDef->type = TACType_Def;
        VarDef->dest = node->Ast_union.node.left->Ast_union.IDentifier;
        

        // 放入符号表
        // llvm生成的AST树上定义前面加类型的原因
        // 无法看到Decl的声明 Const int 的 信息
        // node->Ast_union.node
        // 假设没有类型检查，假设就一个INT型变量
        pVarsValue varsvalue = initpVarsValue(0, tok_INT, 0, NULL);
        InsertVars(FuncName, VarDef->dest, varsvalue);
        
        VarDef->right = ListGet(IDorCONST);
        ListPopFront(IDorCONST);

        VarDef->node_ID = NODE_ID;
        NODE_ID++;

        pTAC VarDefs_or_Stmt = buildTAC(node->Ast_union.node.next, FuncFrom);
        
        
        conect_TAC(&left, &VarDef);
        conect_TAC(&left, &VarDefs_or_Stmt);
        return left;
    }
    else
    {
        //处理数组
        int* temdim;
        int dimcount = handleconstexps(node->Ast_union.node.middle, &temdim);
        
        //放入符号表
        //同上
        pVarsValue varsvalue = initpVarsValue(0, tok_INT, dimcount, temdim);
        InsertVars(FuncName, node->Ast_union.node.left->Ast_union.IDentifier, varsvalue);
        // 赋值语句的TAC
        int* nowdim = malloc(sizeof(int)*(dimcount));
        for (size_t i = 0; i < dimcount; i++)
        {
            nowdim[i] = 0;
        }
        pTAC left = buildTACInitVal(nowdim, node->Ast_union.node.left->Ast_union.IDentifier, node->Ast_union.node.right, 0, FuncFrom, dimcount);
        pTAC next = buildTAC(node->Ast_union.node.next, FuncFrom);
        conect_TAC(&left, &next);
        free(nowdim);
        return left;
        /*
        //处理数组
        int* temdim;
        int dimcount = handleconstexps(node->Ast_union.node.middle, &temdim);
        //放入符号表
        
        int sum = 1;
        for (size_t i = 0; i < dimcount; i++)
        {
            sum = sum * temdim[i];
        }
        //putinsignal(FuncFrom, 0, tok_INT, dimcount, temdim, node->Ast_union.node.left->Ast_union.IDentifier);
        
        int* nowdim = malloc(sizeof(int)*(dimcount));
        for (size_t i = 0; i < dimcount; i++)
        {
            nowdim[i] = 0;
        }
        pTAC left = buildTACInitVal(nowdim, node->Ast_union.node.left->Ast_union.IDentifier, node->Ast_union.node.right, 0, FuncFrom, dimcount);
        pTAC next = buildTAC(node->Ast_union.node.next, FuncFrom);
        conect_TAC(&left, &next);
        free(nowdim);
        return left;
        /*
        if (node->Ast_union.node.right != NULL)
        {
            int* temvalue;//free的时机？放入表之后？
            int valuecount = handleInitVal;
            handle
        }
        */
    }    
}

//根据维度信息去初始化//初始化 value[]
//指向EXP->ADDEXP
//1220初始化其中的信息，但是仅初始化三地址
pTAC build_InitVal_TAC(past node, int FuncFrom)//有next！
{
    pTAC middle = buildTAC(node->Ast_union.node.middle, FuncFrom);
    pTAC next = buildTAC(node->Ast_union.node.next, FuncFrom);
    conect_TAC(&middle,&next);
    return middle;
}

pTAC build_ConstDecl_TAC(past node, int FuncFrom)//有next？
{
    pTAC ConstDef = buildTAC(node->Ast_union.node.left, FuncFrom);
    pTAC next = buildTAC(node->Ast_union.node.next, FuncFrom);
    conect_TAC(&ConstDef, &next);
    return ConstDef;
}

pTAC build_ConstDef_TAC(past node, int FuncFrom)//有next！
{
    if (NULL == node->Ast_union.node.middle)
    {
        //putinsignal(FuncFrom, tok_CONST, tok_INT, 0, NULL, node->Ast_union.node.left->Ast_union.IDentifier);
        //非数组
        pTAC VarDef = newTACnode();
        pTAC left = buildTAC(node->Ast_union.node.right, FuncFrom);
        VarDef->type = TACType_Def;
        
        // 放入符号表
        // llvm生成的AST树上定义前面加类型的原因
        // 无法看到Decl的声明 Const int 的 信息
        // node->Ast_union.node
        // 假设没有类型检查，假设就一个INT型变量
        pVarsValue varsvalue = initpVarsValue(tok_CONST, tok_INT, 0, NULL);
        InsertVars(FuncName, VarDef->dest, varsvalue);


        VarDef->dest = node->Ast_union.node.left->Ast_union.IDentifier;
        VarDef->right = ListGet(IDorCONST);
        ListPopFront(IDorCONST);
        VarDef->node_ID = NODE_ID;
        NODE_ID++;
        pTAC VarDefs_or_Stmt = buildTAC(node->Ast_union.node.next, FuncFrom);
        
        
        conect_TAC(&left, &VarDef);
        conect_TAC(&left, &VarDefs_or_Stmt);
        return left;
    }
    
    else
    {
        //处理数组
        int* temdim;
        int dimcount = handleconstexps(node->Ast_union.node.middle, &temdim);
        
        //放入符号表
        //同上
        pVarsValue varsvalue = initpVarsValue(tok_CONST, tok_INT, dimcount, temdim);
        InsertVars(FuncName, node->Ast_union.node.left->Ast_union.IDentifier, varsvalue);
        // 赋值语句的TAC
        int* nowdim = malloc(sizeof(int)*(dimcount));
        for (size_t i = 0; i < dimcount; i++)
        {
            nowdim[i] = 0;
        }
        pTAC left = buildTACInitVal(nowdim, node->Ast_union.node.left->Ast_union.IDentifier, node->Ast_union.node.right, 0, FuncFrom, dimcount);
        pTAC next = buildTAC(node->Ast_union.node.next, FuncFrom);
        conect_TAC(&left, &next);
        free(nowdim);
        return left;
    }
    
}

// -------- 往下没有细看 -------- //

//生成维度信息dimcount & dim[] 放到一个专用的栈里面？
pTAC build_ConstExps_TAC(past node, int FuncFrom)//有next！
{
    pTAC left = buildTAC(node->Ast_union.node.left, FuncFrom);
    pTAC next = buildTAC(node->Ast_union.node.next, FuncFrom);
    conect_TAC(&left,&next);
    return left;
}

//指向CONSTEXP->ADDEXP
pTAC build_ConstInitVal_TAC(past node, int FuncFrom)//有next？！
{
    pTAC middle = buildTAC(node->Ast_union.node.middle, FuncFrom);
    pTAC next = buildTAC(node->Ast_union.node.next, FuncFrom);
    conect_TAC(&middle,&next);
    return middle;
}

pTAC build_Block_TAC(past node, int FuncFrom)//有next？
{
    pTAC BlockItems_Decl_Or_Stmt = buildTAC(node->Ast_union.node.middle, FuncFrom);
    pTAC next = buildTAC(node->Ast_union.node.next, FuncFrom);
    conect_TAC(&BlockItems_Decl_Or_Stmt, &next);
    return BlockItems_Decl_Or_Stmt;
}

pTAC build_Stmt_TAC(past node, int FuncFrom)//有next？！
{
    pTAC Stmt;
    if(node->Ast_union.node.t_Token2 != -1)
        switch (node->Ast_union.node.t_Token2)
        {
            case tok_ASSIGN:
            {
                pTAC Exp = buildTAC(node->Ast_union.node.right, FuncFrom);
                pTAC LVal = buildTAC(node->Ast_union.node.left, FuncFrom);

                pTAC assign = newTACnode();
                assign->type = TACType_Def;


                assign->dest = ListGet();
                ListPopFront(IDorCONST);
                assign->right = ListGet();
                ListPopFront(IDorCONST);
                assign->node_ID = NODE_ID;
                NODE_ID++;

                pTAC next = buildTAC(node->Ast_union.node.next, FuncFrom);
                conect_TAC(&Exp, &LVal);
                conect_TAC(&Exp, &assign);
                conect_TAC(&Exp, &next);
                
                Stmt = Exp;
                return Stmt;
                break;
            }
            case tok_ELSE:
            {

                pTAC gotoStmt1 = newTACnode();
                gotoStmt1->type = TACType_IfGo;
                

                //Cond在node->Ast_union.node.left
                //如何处理Cond的left和right//栈？
                //还是说直接放到EXP去解释？
                pTAC Cond = buildTAC(node->Ast_union.node.left, FuncFrom);//解释(COND)Exp;生成EXP的TAC怎么获取结果值呢
                gotoStmt1->right = ListGet();
                ListPopFront(IDorCONST);
                //gotoStmt1->op = node->Ast_union.node.left->Ast_union.node.t_Token1;
                //gotoStmt1->left = ListGet();
                ListPopFront(IDorCONST);
                // gotoStmt1->dest = ;
                gotoStmt1->node_ID = NODE_ID;
                NODE_ID++;

                pTAC gotoELSE = newTACnode();
                gotoELSE->type = TACType_Go;
                gotoELSE->node_ID = NODE_ID;
                NODE_ID++;

                int Stmt1node = NODE_ID;
                pTAC Stmt1 = buildTAC(node->Ast_union.node.middle, FuncFrom);
                
                pTAC gotoELSE2 = newTACnode();
                gotoELSE2->type = TACType_Go;
                gotoELSE2->node_ID = NODE_ID;
                NODE_ID++;

                int Stmt2node = NODE_ID;
                pTAC Stmt2 = buildTAC(node->Ast_union.node.right, FuncFrom);

                gotoStmt1->dest = buildNUM(Stmt1node);
                gotoELSE->dest = buildNUM(Stmt2node);
                gotoELSE2->dest = buildNUM(NODE_ID);

                pTAC next = buildTAC(node->Ast_union.node.next, FuncFrom);
                conect_TAC(&Cond, &gotoStmt1);
                conect_TAC(&Cond, &gotoELSE);
                conect_TAC(&Cond, &Stmt1);
                conect_TAC(&Cond, &gotoELSE2);
                conect_TAC(&Cond, &Stmt2);
                conect_TAC(&Cond, &next);
                Stmt = Cond;
                return Stmt;
                break;
            }
            default:
                break;
        }
    else
    {
        switch (node->Ast_union.node.t_Token1)
        {
            case tok_WHILE:
            {
                //Cond在node->Ast_union.node.left
                //如何处理Cond的left和right
                //分开解释？
                //用栈传right和left？
                //还是说直接放到EXP去解释？
                int whilestart = NODE_ID;
                pTAC Cond = buildTAC(node->Ast_union.node.left, FuncFrom);//解释(COND)Exp;生成EXP的TAC怎么获取结果值呢
                
                pTAC gotoStmt1 = newTACnode();
                gotoStmt1->type = TACType_IfGo;
                gotoStmt1->node_ID = NODE_ID;
                NODE_ID++;

                gotoStmt1->right = ListGet();//从栈中获取
                ListPopFront(IDorCONST);
                //gotoStmt1->op = node->Ast_union.node.left->Ast_union.node.t_Token1;
                //gotoStmt1->left = ListGet();//从栈中获取
                ListPopFront(IDorCONST);

                pTAC gotoEND = newTACnode();
                gotoEND->type = TACType_Go;
                gotoEND->node_ID = NODE_ID;
                NODE_ID++;

                int Stmtstart = NODE_ID;
                pTAC Stmt1 = buildTAC(node->Ast_union.node.middle, FuncFrom);
                pTAC gotowhilestart = newTACnode();
                gotowhilestart->dest = buildNUM(whilestart);
                gotowhilestart->node_ID = NODE_ID;
                NODE_ID++;
                gotowhilestart->type = TACType_Go;


                int Stmtend = NODE_ID;
                backfill(Stmt1, Stmtstart, Stmtend);//回填Stmt1中的BREAK和CONTINUE，给出函数的头部，返回空;

                gotoStmt1->dest = buildNUM(Stmtstart);
                gotoEND->dest = buildNUM(Stmtend);



                pTAC next = buildTAC(node->Ast_union.node.next, FuncFrom);


                conect_TAC(&Cond, &gotoStmt1);
                conect_TAC(&Cond, &gotoEND);
                conect_TAC(&Cond, &Stmt1);
                conect_TAC(&Cond, &gotowhilestart);
                conect_TAC(&Cond, &next);
                Stmt = Cond;
                return Stmt;
                break;
            }
            case tok_IF:
            {
                pTAC gotoStmt1 = newTACnode();
                gotoStmt1->type = TACType_IfGo;
                

                pTAC Cond = buildTAC(node->Ast_union.node.left, FuncFrom);//解释(COND)Exp;生成EXP的TAC怎么获取结果值呢
                gotoStmt1->right = ListGet();//从栈中获取
                ListPopFront(IDorCONST);
                //gotoStmt1->op = node->Ast_union.node.left->Ast_union.node.t_Token1;
                //gotoStmt1->left = ListGet();//从栈中获取
                ListPopFront(IDorCONST);
                // gotoStmt1->dest = ;
                gotoStmt1->node_ID = NODE_ID;
                NODE_ID++;

                pTAC gotoEND = newTACnode();
                gotoEND->type = TACType_Go;
                gotoEND->node_ID = NODE_ID;
                NODE_ID++;

                int Stmtstart = NODE_ID;
                pTAC Stmt1 = buildTAC(node->Ast_union.node.middle, FuncFrom);
                int Stmtend = NODE_ID;

                gotoStmt1->dest = buildNUM(Stmtstart);
                gotoEND->dest = buildNUM(Stmtend);


                pTAC Stmtnext = buildTAC(node->Ast_union.node.next, FuncFrom);
                conect_TAC(&Cond, &gotoStmt1);
                conect_TAC(&Cond, &gotoEND);
                conect_TAC(&Cond, &Stmt1);
                conect_TAC(&Cond, &Stmtnext);
                Stmt = Cond;
                return Stmt;
                break;
            }
            case tok_BREAK:
            {
                pTAC GOTO_WHILE = newTACnode();
                GOTO_WHILE->type = tok_BREAK;
                GOTO_WHILE->node_ID = NODE_ID;
                NODE_ID++;
                Stmt = GOTO_WHILE;
                pTAC next = buildTAC(node->Ast_union.node.next, FuncFrom);
                conect_TAC(&Stmt, &next);
                return Stmt;
                break;
            }
            case tok_CONTINUE:
            {
                pTAC GOTO_WHILE = newTACnode();
                GOTO_WHILE->type = tok_CONTINUE;
                GOTO_WHILE->node_ID = NODE_ID;
                NODE_ID++;
                Stmt = GOTO_WHILE;
                pTAC next = buildTAC(node->Ast_union.node.next, FuncFrom);
                conect_TAC(&Stmt, &next);
                return Stmt;
                break;
            }
            case tok_RETURN:
            {
                pTAC Exp_TAC;
                if (node->Ast_union.node.left != NULL)
                {
                    Exp_TAC = buildTAC(node->Ast_union.node.left, FuncFrom);
                }
                else
                {
                    Exp_TAC = NULL;
                }
                //！;
                //怎么返回,有相应的TAC语句吗;
                pTAC Return_TAC = newTACnode();
                Return_TAC->type = TACType_Return;
                Return_TAC->node_ID = NODE_ID;
                NODE_ID++;

                Return_TAC->dest = ListGet();//从栈中获取
                ListPopFront(IDorCONST);
                
                conect_TAC(&Exp_TAC, &Return_TAC);
                Stmt = Exp_TAC;
                pTAC next = buildTAC(node->Ast_union.node.next, FuncFrom);
                conect_TAC(&Stmt, &next);
                return Stmt;
                break;
            }
            case -1://Exp
            {
                //怎么调用函数？;//一元表达式UnaryExp调用函数
                pTAC Return_TAC = buildTAC(node->Ast_union.node.left, FuncFrom);
                pTAC next = buildTAC(node->Ast_union.node.next, FuncFrom);
                conect_TAC(&Return_TAC, &next);
                return Return_TAC;
                break;
            }
            default:
                break;
        }
    }
    
}

pTAC build_LVal_TAC(past node, int FuncFrom)//有next？
{
    if (node->Ast_union.node.right == NULL)//非数组
    {
        pTAC left = buildTAC(node->Ast_union.node.left, FuncFrom);
        pTAC next = buildTAC(node->Ast_union.node.next, FuncFrom);
        conect_TAC(&left,&next);
        return left;
    }
    
    else//数组
    {
        //处理数组
        int* temdim;
        int dimcount = handleconstexps(node->Ast_union.node.right, &temdim);
        //放入符号表
        char* name = ijktooffset(FuncName, dimcount, temdim, node->Ast_union.node.left->Ast_union.IDentifier);
        ListPushFront(IDorCONST, name);
        pTAC next = buildTAC(node->Ast_union.node.next, FuncFrom);
        return next;
        /*
        char * temget = node->Ast_union.node.left->Ast_union.IDentifier;!不行
        int offset = getoffset(FuncFrom, temget, node->Ast_union.node.right);
        int size = 0;
        int tem = offset;
        do
        {
            size++;
            tem = tem / 10;
        } while (tem != 0);
        int newsize = sizeof(temget) + size + 1 + 1;
        char* temname = malloc(sizeof(char)*newsize);
        tem = sizeof(temget);
        for (size_t i = 0; i < tem; i++)
        {
            temname[i] = temget[i];
        }
        temname[tem] = '#';temname[newsize-1] = 0;
        
        for (size_t i = tem + 1; i < newsize-1; i++)
        {
            int result = 1;
            int exponent = size - 1;
            while (exponent != 0)
            {
                result *= 10;
                --exponent;
            }
            temname[i] = offset/result + 48;
            offset = offset - offset/result;
        }
        ListPushFront(IDorCONST, temname);
        pTAC next = buildTAC(node->Ast_union.node.next, FuncFrom);
        return next;*/
        
    }
    
}

pTAC build_Exps_TAC(past node, int FuncFrom)//有next！
{
    pTAC left = buildTAC(node->Ast_union.node.left, FuncFrom);
    pTAC next = buildTAC(node->Ast_union.node.next, FuncFrom);
    conect_TAC(&left,&next);
    return left;
}

pTAC build_UnaryExp_TAC(past node, int FuncFrom)//有next
{
    if (node->Ast_union.node.t_Token1 == -1)
    {
        pTAC right = buildTAC(node->Ast_union.node.right, FuncFrom);
        pTAC left = newTACnode();
        
        left->type = TACType_BeginFunc;

        left->dest = node->Ast_union.node.left->Ast_union.IDentifier;
        pTAC next = buildTAC(node->Ast_union.node.next, FuncFrom);
        //查函数是否有返回值，如果有就加入returnval
        //char * temID = "returnval";
        //ListPushFront(IDorCONST, temID);
        left->node_ID = NODE_ID;
        NODE_ID++;
        conect_TAC(&right, &left);
        conect_TAC(&right, &next);
        return right;
    }
    else
    {
        pTAC cur = newTACnode();
        
        cur->type = TACType_Def;
        
        pTAC left = buildTAC(node->Ast_union.node.left, FuncFrom);
        //cur->left = 0;
        cur->op = node->Ast_union.node.t_Token1;
        cur->right = ListGet(IDorCONST);
        ListPopFront(IDorCONST);

        char * temID = newTempID(FuncFrom);
        cur->dest = temID;//这个也应该入栈
        ListPushFront(IDorCONST, temID);

        temID = "#0";
        cur->left = temID;

        pTAC next = buildTAC(node->Ast_union.node.next, FuncFrom);
        
        cur->node_ID = NODE_ID;
        NODE_ID++;
        
        conect_TAC(&left, &cur);
        conect_TAC(&left, &next);
        return left;
        
    }
    
}

//实参传递？？？？
pTAC build_FuncRParams_TAC(past node, int FuncFrom)//有next？
{
    
    pTAC TAC_FuncRParam = newTACnode();
    //非数组情况//数组情况在传参的时候添加维度信息
        TAC_FuncRParam->type = (enum TACType)TACType_Param;
        
        pTAC left;
        
        
        
        left = buildTAC(node->Ast_union.node.left, FuncFrom);
        TAC_FuncRParam->node_ID = NODE_ID;
        NODE_ID++;
        
        TAC_FuncRParam->dest = ListGet(IDorCONST);
        ListPopFront(IDorCONST);

        
        
    pTAC TAC_FuncRParamss = buildTAC(node->Ast_union.node.next, NODE_ID);
    conect_TAC(&left, &TAC_FuncRParam);
    conect_TAC(&left, &TAC_FuncRParamss);
    return left;
}

pTAC build_Expr_TAC(past node, int FuncFrom)//有next？！
/*声明一个中间变量，存到符号表中，目的地是这个中间变量，然后这个中间变量放到栈中？*/
{
    
    pTAC left = buildTAC(node->Ast_union.node.left, FuncFrom);
    pTAC right = buildTAC(node->Ast_union.node.right, FuncFrom);
    pTAC TAC_Expr = newTACnode();
    TAC_Expr->type = TACType_Def;
        
        TAC_Expr->right = ListGet(IDorCONST);
        ListPopFront(IDorCONST);
        TAC_Expr->op = node->Ast_union.node.t_Token1;
        TAC_Expr->left = ListGet(IDorCONST);
        ListPopFront(IDorCONST);
        char * temID = newTempID(FuncFrom);
        TAC_Expr->dest = temID;//这个也应该入栈
        ListPushFront(IDorCONST, temID);
    //！;
    //临时变量也应该入栈
    TAC_Expr->node_ID = NODE_ID;
    NODE_ID++;
    conect_TAC(&left, &right);
    conect_TAC(&left, &TAC_Expr);
    return left;
    
}

/*
//变量初值			yes
InitVal			: 	Exp												{$$ = $1;}
					|	Y_LBRACKET 					Y_RBRACKET		{$$ = newInitVal(NULL, NULL, NULL);}
					|	Y_LBRACKET InitVal			Y_RBRACKET		{$$ = newInitVal(NULL, $2, NULL);}
					| 	Y_LBRACKET InitVal InitVals Y_RBRACKET		{$$ = newInitVal(NULL, $2, $3);}
					;
//变量初值s				
InitVals		:	Y_COMMA InitVal 								{$$ = $2;}
					|Y_COMMA InitVal InitVals						{$$ = newInitVals($2, $3);}
					;*/
pTAC buildTACInitVal(int dim[], char name[], past node, int dimcount, int FuncFrom, int dimmax)
{
    if (node == NULL)
    {
        return NULL;
        /*
         三维数组：a[m][n][o]
          三维数组计算a[i][j][k]的公式为d=i*n*o+j*o+k
        */
    }
    if (node->Ast_union.node.middle->ast_ID == InitVal)
    {
        pTAC head = buildTACInitVal(dim, name, node->Ast_union.node.middle, dimcount, FuncFrom, dimmax);
        dim[dimcount] = dim[dimcount] + 1;
        pTAC next = buildTACInitVal(dim, name, node->Ast_union.node.middle, dimcount+1, FuncFrom, dimmax);
        conect_TAC(&head, &next);
        return head;
    }
    else
    {
        past cur = node->Ast_union.node.middle;
        
        pTAC headTAC = NULL; 
        for (; cur != NULL && cur->ast_ID != InitVal; cur = cur->Ast_union.node.next)
        {
            pTAC preTAC = buildTAC(cur, FuncFrom);
            pTAC nowTAC = newTACnode();
            nowTAC->type = TACType_Def;
            nowTAC->dest = ijktooffset(FuncName, dimmax , dim, name);
            nowTAC->right = ListGet(IDorCONST);
            ListPopFront(IDorCONST);
            nowTAC->node_ID = NODE_ID;
            NODE_ID++;

            dim[dimmax-1] = dim[dimmax-1] + 1;
            conect_TAC(&headTAC, &preTAC);
            conect_TAC(&headTAC, &nowTAC);
        }
        
        if (cur != NULL && cur->ast_ID == InitVal)
        {
            dim[dimmax-1] = 0;
            dim[dimcount] = dim[dimcount] + 1;
            pTAC next = buildTACInitVal(dim, name, cur, dimcount+1, FuncFrom, dimmax);
            dim[dimmax-1] = 0;
            dim[dimcount+1] = dim[dimcount+1] + 1;
            pTAC nextnext = buildTACInitVal(dim, name, cur->Ast_union.node.next, dimcount+2, FuncFrom, dimmax);
            conect_TAC(&headTAC, &next);
            conect_TAC(&headTAC, &nextnext);
        }
        return headTAC;
    }
}

void printfTAC(pTAC node)
{
    pTAC cur = node;
    char * tem;
    do
    {
        if (cur->type == TACType_Def)
        {
            printf("%d : ",cur->node_ID);
        
            printf("%s := ",cur->dest);
            tem = cur->left;
            if (tem != 0)
            {
                printf("%s ",tem);
                showToken(cur->op);
            }
            tem = cur->right;
            if (tem != 0)
                printf(" %s",tem);    
        }
        else if (cur->type == TACType_Go)
        {
            printf("%d : ",cur->node_ID);
            printf(" %s ","goto");
            printf(" %s ",cur->dest);
        }
        else if (cur->type == TACType_IfGo)
        {
            printf("%d : ",cur->node_ID);
            printf(" %s ","if");
            printf(" %s ",cur->right);
            printf(" %s ","goto");
            printf(" %s ",cur->dest);
        }
        else if (cur->type == TACType_BeginFunc)
        {
            printf("%d : ",cur->node_ID);
            printf(" %s ","CALL");
            printf(" %s ",cur->dest);
        }
        else if (cur->type == TACType_EndFunc)
        {
            printf("%d : ",cur->node_ID);
            printf(" %s ","EndFunc");
        }
        else if (cur->type == TACType_Param)
        {
            printf("%d : ",cur->node_ID);
            printf(" %s ","Param");
            printf(" %s ",cur->dest);
            if ('*' == cur->op)
            {
                printf(" * ");
            }
            
        }
        else if (cur->type == TACType_Return)
        {
            printf("%d : ",cur->node_ID);
            printf(" %s ","return");
            printf(" %s ",cur->dest);
        }
        else if (cur->type == TACType_DefFunc)
        {
            printf("%d : ",cur->node_ID);
            printf(" %s ","DefFunc");
            printf(" %s ",cur->dest);
            printf(" %d ",cur->op);
        }
        cur = cur->next;
        printf("\n");
    } while (cur != NULL );
    initmap();
    buildliveness(node);
    showallliveness();
}
